/*
 * denso_adc.c
 *
 *  Created on: Nov 16, 2012
 *      Author: Andrey Belomutskiy
 */

#include <stm32f4xx_tim.h>
#include "adc_denso.h"
#include "io.h"
#include "distributor_emulator.h"
#include "rficonsole.h"

#define TICKS 2
//#define FREQ 10000
#define FREQ (2 * 62500)

PWMDriver *pwm_driver = &PWMD1;
volatile int dz_de_pwm_counter = 0;
volatile int chCounter1 = 0;
volatile int chCounter2 = 0;

static void dz_pwmpcb(PWMDriver *pwmp);

/*
 * PWM configuration structure.
 * Cyclic callback enabled, channels 1 and 4 enabled without callbacks,
 * the active state is different on different channels.
 */

myfloat adcWave = FREQ / 2.0 / 135.8;

static void channel2callback(PWMDriver *pwmp) {
	chCounter2++;
}

static void channel1callback(PWMDriver *pwmp) {
	chCounter1++;
}

/*
 * PWM cyclic callback.
 */
static void dz_pwmpcb(PWMDriver *pwmp) {
	(void) pwmp;

	chSysLockFromIsr()
	;
	dz_de_pwm_counter++;

	int pinValue = waveState(0, dz_de_pwm_counter, adcWave, 0, 0.5);

//	setPinValue(DE_ADC_IO_PORT, DE_ADC_WAVE_PIN, pinValue);

	/* Changes the channels pulse width, the change will be effective
	 starting from the next cycle.*/

//	pwmEnableChannelI(pwm_driver, 2,
	//PWM_FRACTION_TO_WIDTH(pwm_driver, 1, pinValue));
	pwmEnableChannelI(pwm_driver, DENSO_SERIAL_CLOCK_CHANNEL,
			PWM_FRACTION_TO_WIDTH(pwm_driver, TICKS, 1));

	int dz_de_pwm_counter2 = dz_de_pwm_counter % 300;
	int signal = 1;

	if (dz_de_pwm_counter2 == 0 || dz_de_pwm_counter2 == 2)
		signal = 0;

	if (dz_de_pwm_counter2 == 100 || dz_de_pwm_counter2 == 103)
		signal = 0;

	if (dz_de_pwm_counter2 == 200)
		signal = 0;

//	if (dz_de_pwm_counter2 == 0 || dz_de_pwm_counter2 == 2 || dz_de_pwm_counter2 == 3 ||
//			dz_de_pwm_counter2 == 4 || dz_de_pwm_counter2 == 5)
//		signal = 0;

//	if (dz_de_pwm_counter2 == 100 || dz_de_pwm_counter2 == 103 || dz_de_pwm_counter2 == 105)
//		signal = 0;

	pwmEnableChannelI(pwm_driver, DENSO_SERIAL_COMMAND_CHANNEL,
			PWM_FRACTION_TO_WIDTH(pwm_driver, 1, signal));

	chSysUnlockFromIsr();
}

static PWMConfig dz_pwmcfg = { FREQ, TICKS, dz_pwmpcb, { // now go 4 channels
		{ PWM_OUTPUT_ACTIVE_HIGH, channel1callback }, // CH1
				{ PWM_OUTPUT_DISABLED, channel2callback }, // CH2
				{ PWM_OUTPUT_ACTIVE_LOW, NULL }, // CH3
				{ PWM_OUTPUT_DISABLED, NULL }, // CH4
		},
		/* HW dependent part.*/
		0 };

static WORKING_AREA(tempThreadSpace, 256);

void tempThread() {

	while (1) {
		print("full %d ch %d %d\r\n", dz_de_pwm_counter, chCounter1,
				chCounter2);
		chThdSleepMilliseconds(300);
	}
}

void initDensoAdc2() {
	pwmStart(pwm_driver, &dz_pwmcfg);
//	palSetPadMode(GPIOD, 12, PAL_MODE_ALTERNATE(2)); // TIM4_CH1, AF2
//	palSetPadMode(GPIOD, 15, PAL_MODE_ALTERNATE(2)); // TIM4_CH4, AF2

	palSetPadMode(DENSO_SERIAL_COMMAND_IO_PORT, DENSO_SERIAL_COMMAND_PIN,
			PAL_MODE_ALTERNATE(DENSO_SERIAL_CLOCK_MODE_ALT));
// TIM1_CH1, AF1 - control, green

	//	palSetPadMode(GPIOA, TIM1_PA9, PAL_MODE_ALTERNATE(1));
// TIM1_CH2, AF1

//	palSetPadMode(DENSO_SERIAL_CLOCK_IO_PORT, 9,
//			PAL_MODE_ALTERNATE(DENSO_SERIAL_CLOCK_MODE_ALT));

	palSetPadMode(DENSO_SERIAL_CLOCK_IO_PORT, DENSO_SERIAL_CLOCK_PIN,
			PAL_MODE_ALTERNATE(DENSO_SERIAL_CLOCK_MODE_ALT));

	palSetPadMode(DENSO_SERIAL_CLOCK_IO_PORT, 9, PAL_MODE_INPUT);
//	palSetPadMode(DENSO_SERIAL_CLOCK_IO_PORT, 9,
//			PAL_MODE_INPUT_PULLDOWN);

	// TIM1_CH3, AF1 - 62.5 KHz clock, - blue

//	palSetPadMode(GPIOA, TIM1_PA11, PAL_MODE_ALTERNATE(1));
// TIM1_CH4, AF1

//	palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(1)); // TIM2_CH4, AF1

	TIM_ICInitTypeDef timer_ic;
	timer_ic.TIM_Channel = TIM_Channel_2;
	timer_ic.TIM_ICPolarity = TIM_ICPolarity_Rising;
	timer_ic.TIM_ICSelection = TIM_ICSelection_DirectTI;
	timer_ic.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	timer_ic.TIM_ICFilter = 0;
	TIM_ICInit(pwm_driver->tim, &timer_ic);

	// channel 2
	TIM_ITConfig(pwm_driver->tim, TIM_IT_CC2, ENABLE);

	chThdCreateStatic(tempThreadSpace, sizeof(tempThreadSpace), NORMALPRIO,
			tempThread, NULL );

}

